package com.yanxi.user.web.config;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.yanxi.user.web.common.util.ManagedChannelUtils;
import com.yanxi.user.web.grpc.pullConfigService.PullConfigRequest;
import com.yanxi.user.web.grpc.pullConfigService.PullConfigResponse;
import com.yanxi.user.web.grpc.pullConfigService.PullConfigServiceGrpc;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.cloud.context.refresh.ContextRefresher;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MapPropertySource;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.stereotype.Service;

import java.util.Map;
import java.util.concurrent.Executors;
import java.util.logging.Logger;

@Service
@RefreshScope
public class ConfigService{

    @Value("${grpc.client.xyregiserve.port}")
    private String regiservePort;

    @Value("${grpc.client.xyregiserve.url}")
    private String regiserveUrl;

    @Autowired
    private ConfigurableApplicationContext applicationContext;

    @Autowired
    private ContextRefresher contextRefresher;

    private static final String PROPERTY_SOURCE_NAME = "databaseProperties";

    private static final Logger logger = Logger.getLogger(PullConfigLoader.class.getName());

    public Map<String, Object> refreshConfig() throws Exception {

        ManagedChannelUtils.runWithManagedChannel(regiserveUrl, regiservePort, channel -> {
            try {
                PullConfigServiceGrpc.PullConfigServiceBlockingStub pullConfigServiceBlockingStub = PullConfigServiceGrpc.newBlockingStub(channel);

                /**
                 * 拉取配置
                 */
                PullConfigResponse response = pullConfigServiceBlockingStub.getConfigByTag(PullConfigRequest
                        .newBuilder()
                        .setStr("user")
                        .build());

                /**
                 * 调用成功
                 */
                if (response.getStatus() == 200) {

                    logger.info("ServerConfig loading Success");

                    /**
                     * 类型转化
                     */
                    Map<String, Object> newConfig = JSON.parseObject(response.getData(), new TypeReference<Map<String, Object>>() {
                    });

                    /**
                     * 获取当前环境
                     */
                    ConfigurableEnvironment environment = applicationContext.getEnvironment();

                    /**
                     * 创建新的PropertySource
                     */
                    MapPropertySource newPropertySource = new MapPropertySource(PROPERTY_SOURCE_NAME, newConfig);

                    /**
                     * 获取PropertySourcess
                     */
                    MutablePropertySources propertySources = environment.getPropertySources();

                    /**
                     * 替换或添加新的PropertySource
                     */
                    if (propertySources.contains(PROPERTY_SOURCE_NAME)) {
                        propertySources.replace(PROPERTY_SOURCE_NAME, newPropertySource);
                    } else {
                        propertySources.addFirst(newPropertySource);
                    }

                    /**
                     * 异步刷新
                     */
                    Executors.newSingleThreadExecutor().execute(() -> contextRefresher.refresh());

                } else {

                    throw new Exception("ServerConfig return code error");
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        });

        return null;
    }
}

